home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / UI / Disptch.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  29.0 KB  |  1,071 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Disptch.cpp
  3.  
  4.     Contains:    Implementation of class ODDispatcher
  5.  
  6.     Owned by:    Richard Rodseth
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     5/01/96    NP        1300091,1282521: Replace badly written bug
  13.                                     workaround, IntlTSMEvent, with TSMEvent.
  14.         <50>    10/17/95    jpa        1292659: Ignore exceptions sending null
  15.                                     events to parts
  16.         <49>    10/10/95    DM        1277216: GM:API: Dont return ODPoint from
  17.                                     GetWindowPoint()
  18.         <48>     10/3/95    TJ        Changes done by RefBall Team
  19.         <47>      9/6/95    RR        #1282075 ADded ODVolatile
  20.         <46>     8/29/95    RR        # 1276401 Respect Mouse Focus
  21.         <45>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  22.         <44>     8/23/95    NP        1264142: Don't Release null object.
  23.         <43>     8/15/95    RR        #1222870 Moved NULL handling to end of
  24.                                     method to allow patching/monitors
  25.         <42>      8/3/95    RR        #1257260: Collapse B classes. Remove
  26.                                     somInit methods. Don't call IsInitialized
  27.                                     or SubclassResponsibility
  28.         <41>     6/29/95    NP        1263893: Fix TSM support.
  29.         <40>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  30.                                     refcount is wrong in
  31.                                     ODRefCntObjectsomUninit.
  32.         <39>     6/23/95    CC        1256943: MouseRegionIsInvalid: Replaced
  33.                                     StillDown with Button.
  34.         <38>     6/22/95    NP        1260250: Set up correctly for call to
  35.                                     CallEventHandler.
  36.         <37>     6/20/95    JP        1251250: ChangedReleaseExtension into
  37.                                     Release
  38.         <36>     6/15/95    RR        #1254828/1255536 Added Redispatch
  39.         <35>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  40.                                     StdTypes.r -> ODTypes.r
  41.         <34>     5/31/95    RR        #1251403 Release after AcquirePart
  42.         <33>     5/26/95    RR        #1251403: Multithreading naming support
  43.         <32>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  44.         <31>     5/21/95    NP        1251212: Wrap procs with UPPs.
  45.         <30>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  46.                                     refcount
  47.         <29>     5/10/95    RR        #1239139 MouseEnter etc.  over active
  48.                                                                         border go to container. Don't send
  49.                                     until mouse up.
  50.         <28>     5/10/95    RR         #1239139 MouseEnter etc.  over active
  51.                                     border go to container. Don't send until mouse up.
  52.         <27>     4/27/95    eeh        1230798: call part::ReleaseExtension
  53.         <26>      4/7/95    RR        #1216618 Added SOM_TRY etc.
  54.         <25>      4/4/95    RR        # 1211085 Removed fThreadsAvailable,
  55.                                     #1220104 Use ODObjectsAreEqual, #1228161
  56.                                     RegisterIdle does not update frequency if
  57.                                     called twice
  58.         <24>     3/20/95    jpa        Cooperative thread support [1167943]. Moved
  59.                                     bg click handler installation to private
  60.                                     impl file [1220704].
  61.         <23>     3/10/95    RR        # 1187137 Set Cursor to arrow in
  62.                                     InvalidateFacetUnderMouse
  63.         <22>     2/24/95    jpa        Install BG-mouse-down handler [1220704].
  64.                                     Use ODNewRgn. [1220810]
  65.         <21>     2/20/95    TÇ        #1221861 BB: Incomplete AOCE support needs
  66.                                     to be removed from OpenDoc
  67.         <20>     1/31/95    RR        # 1206909 Pass ev to
  68.                                     RemoveUnregisteredIdlers
  69.         <19>     1/25/95    jpa        Include StdExts.xh [1206907]
  70.         <18>     1/13/95    RR        Replace calls to MouseEnter etc with calls
  71.                                     to HandleEvent
  72.         <17>     1/12/95    jpa        Don't use obsolete Toolbox names [1211211].
  73.                                     Change qd --> ODQDGlobals [1210936]
  74.         <16>      1/9/95    NP        1194880: SemtIntf name changes.
  75.         <15>    11/28/94    RR        Prepare for thread support
  76.         <14>     9/30/94    RR        #1167950 Allow unregistering while idling.
  77.                                     Call RemoveUnregisteredIdlers in
  78.                                     HandleNULLEvent
  79.         <13>     9/29/94    RA        1189812: Mods for 68K build.
  80.         <12>     9/20/94    NP        1187682: Initial TSM support.
  81.         <11>     9/20/94    RR        #1154046 Moved ref counting into IdleList
  82.                                     methods so that an unregistered part is not
  83.                                     released. #1156594 Call
  84.                                     WindowState->HandleAOCEMailerEvent instead
  85.                                     of calling SMPMailerEvent directly.
  86.         <10>      9/2/94    eeh        #?: added SMPMailerEvent call to enable use
  87.                                     of mailer until Richard and I agree on a
  88.                                     cleaner fix to a bug in his hamper.
  89.          <9>     8/31/94    TÇ        #1183129, #1183116, #1183119, #1183111:
  90.                                     Lots of ErrorCode cleanup.
  91.          <8>     8/15/94    JBS        1181156: UI API Cleanup
  92.          <7>     8/10/94    JBS        1179919: coordinate system bias changes
  93.          <6>      8/4/94    eeh        bug 1177981: add
  94.                                     ODDispatcherGetDispatchModule
  95.          <5>     7/27/94    eeh        Changes necessitated by WinStat.idl changes
  96.          <4>     7/26/94    eeh        ODQDPoint->Point
  97.          <3>     6/30/94    CG        Moved InitStandardDispatchModule to
  98.                                     InitDispatch from InitSession.
  99.          <2>     9/27/94    RR        Call InitBaseDispatcher
  100.          <1>     9/26/94    RR        first checked in
  101.  
  102.     To Do:
  103.         * Get Gestalt bit for gestaltHasBGMouseDown.
  104.         * Call SetBgndMouseHandler via PrivateInterfaceLib if it's exported therefrom.
  105.         * Check whether bg mousedown handler calls are exported from PrivateInterfaceLib
  106.             and use those if they are (for Copland compatibility)
  107.         
  108.     In Progress:
  109.         
  110. */
  111.  
  112.  
  113. /*
  114.  *  This file was generated by the SOM Compiler.
  115.  *  Generated using: 
  116.  *      SOM Emitter emitxtm.dll: somc/smmain.c
  117.  */
  118.  
  119. #define ODDispatcher_Class_Source
  120. #define VARIABLE_MACROS
  121. #include <Disptch.xih>
  122.  
  123. #ifndef SOM_ODDispatchModule_xh
  124. #include "DispMod.xh"
  125. #endif
  126.  
  127. #ifndef SOM_ODWindowState_xh
  128. #include "WinStat.xh"
  129. #endif
  130.  
  131. #ifndef SOM_ODWindow_xh
  132. #include "Window.xh"
  133. #endif
  134.  
  135. #ifndef SOM_ODSession_xh
  136. #include "ODSessn.xh"
  137. #endif
  138.  
  139. #ifndef _TEMPOBJ_
  140. #include <TempObj.h>
  141. #endif
  142.  
  143. #ifndef _IDLELIST_
  144. #include "IdleList.h"
  145. #endif
  146.  
  147. #ifndef _ORDCOLL_
  148. #include "OrdColl.h"
  149. #endif
  150.  
  151. #ifndef _DISPTABL_
  152. #include "DispTabl.h"
  153. #endif
  154.  
  155. #ifndef SOM_ODFacet_xh
  156. #include "Facet.xh"
  157. #endif
  158.  
  159. #ifndef SOM_ODFrame_xh
  160. #include "Frame.xh"
  161. #endif
  162.  
  163. #ifndef SOM_ODPart_xh
  164. #include "Part.xh"
  165. #endif
  166.  
  167. #ifndef _EXCEPT_
  168. #include "Except.h"
  169. #endif
  170.  
  171. #ifndef SOM_ODStandardDispatchModule_xh
  172. #include <StdDisp.xh>
  173. #endif
  174.  
  175. #ifndef _ODDEBUG_
  176. #include "ODDebug.h"
  177. #endif
  178.  
  179. #ifndef SOM_ODArbitrator_xh
  180. #include <Arbitrat.xh>
  181. #endif
  182.  
  183. #ifndef SOM_ODSemanticInterface_xh
  184. #include <SemtIntB.xh>
  185. #endif
  186.  
  187. #ifndef SOM_ODAppleEvent_xh
  188. #include <ODAplEvt.xh>
  189. #endif
  190.  
  191. #ifndef _BARRAY_
  192. #include "BArray.h"
  193. #endif
  194.  
  195. #ifndef _ODDESUTL_
  196. #include "ODDesUtl.h"
  197. #endif
  198.  
  199. #ifndef SOM_Module_OpenDoc_Foci_defined
  200. #include <Foci.xh>
  201. #endif
  202.  
  203. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  204. #include <StdExts.xh>
  205. #endif
  206.  
  207. #ifndef _DSPUTILM_
  208. #include "DspUtilM.h"
  209. #endif
  210.  
  211. #ifndef _BGCLICKM_
  212. #include "BGClickM.h"
  213. #endif
  214.  
  215. #ifndef _ODTHREDM_
  216. #include "ODThredM.h"
  217. #endif
  218.  
  219. #ifndef __TEXTSERVICES_
  220. #include "TextServices.h"
  221. #endif
  222.  
  223. #ifndef __GESTALTEQU__
  224. #include <GestaltEqu.h>
  225. #endif
  226.  
  227. #define ODLogEvents 0
  228.  
  229. //------------------------------------------------------------------------------
  230. //    ODDispatcher
  231. //------------------------------------------------------------------------------
  232.  
  233. #pragma segment ODDispatcher
  234.  
  235. #include "DisptchB.cpp"    // Platform-independent methods, if any
  236.  
  237. SOM_Scope void  SOMLINK ODDispatcherRegisterIdle(ODDispatcher *somSelf, Environment *ev,
  238.         ODPart* part,
  239.         ODFrame* frame,
  240.         ODIdleFrequency frequency)
  241. {
  242.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  243.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRegisterIdle");
  244.  
  245.     SOM_TRY
  246.     
  247.         if (part)
  248.             _fIdleList->AddIdle(ev, part, frame, frequency);
  249.  
  250.     SOM_CATCH_ALL
  251.     SOM_ENDTRY
  252. }
  253.  
  254. SOM_Scope void  SOMLINK ODDispatcherUnregisterIdle(ODDispatcher *somSelf, Environment *ev,
  255.         ODPart* part,
  256.         ODFrame* frame)
  257. {
  258.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  259.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherUnregisterIdle");
  260.  
  261.     SOM_TRY
  262.  
  263.         if (part)
  264.             _fIdleList->RemoveIdle(ev, part, frame);
  265.  
  266.     SOM_CATCH_ALL
  267.     SOM_ENDTRY
  268. }
  269.  
  270. SOM_Scope void  SOMLINK ODDispatcherSetIdleFrequency(ODDispatcher *somSelf, Environment *ev,
  271.         ODPart* part,
  272.         ODFrame* frame,
  273.         ODIdleFrequency frequency)
  274. {
  275.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  276.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetIdleFrequency");
  277.  
  278.     SOM_TRY
  279.  
  280.         if (part)
  281.             _fIdleList->SetIdleFrequency(ev, part, frame, frequency);
  282.  
  283.     SOM_CATCH_ALL
  284.     SOM_ENDTRY
  285. }
  286.  
  287. SOM_Scope void  SOMLINK ODDispatcherYield(ODDispatcher *somSelf, Environment *ev,
  288.         ODFrame* frame)
  289. {
  290.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  291.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherYield");
  292.  
  293.     SOM_TRY
  294.  
  295.     /*
  296.         Will Call WaitNextEvent(), masking out all but null and update events.
  297.         Idle events are sent to all but the part that yielded
  298.     */
  299.         const    ODSLong        kODSleepTicks             =     20L;//    Number sleep ticks
  300.     
  301.         EventRecord        eventRec;    
  302.         WaitNextEvent ( updateMask, &eventRec, somSelf->GetSleepTime(ev), somSelf->GetMouseRegion(ev) ) ;
  303.         if (eventRec.what == nullEvent)
  304.             somSelf->HandleNullEvent(ev, (ODEventData*) &eventRec, frame);    // Note Cast
  305.         else
  306.             somSelf->Dispatch(ev, (ODEventData*) &eventRec);
  307.     
  308.  
  309.     SOM_CATCH_ALL
  310.     SOM_ENDTRY
  311. }
  312.  
  313. SOM_Scope void  SOMLINK ODDispatcherSetMouseRegion(ODDispatcher *somSelf, Environment *ev,
  314.         ODRgnHandle area)
  315. {
  316.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  317.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetMouseRegion");
  318.  
  319.     if (area && _fPartMouseRegion)
  320.     {
  321.         CopyRgn(area, _fPartMouseRegion);
  322.     }
  323.  
  324. }
  325.  
  326. SOM_Scope ODRgnHandle  SOMLINK ODDispatcherGetMouseRegion(ODDispatcher *somSelf, Environment *ev)
  327. {
  328.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  329.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetMouseRegion");
  330.  
  331.     SOM_TRY
  332.  
  333.         if (somSelf->MouseRegionIsInvalid(ev))
  334.             somSelf->ComputeMouseRegion(ev);
  335.     
  336.     
  337.     /*
  338.     
  339.             CGrafPort desktopPort;                    // Used for showing cursor region 
  340.             long ticks;                                // Used for showing cursor region 
  341.             GrafPtr savedPort;                        // Used for showing cursor region 
  342.     
  343.             // Cursor region is in global coords. Need to create desktop port 
  344.             GetPort(&savedPort);
  345.             OpenCPort(&desktopPort);
  346.             CopyRgn(GetGrayRgn(), desktopPort.visRgn);
  347.             desktopPort.portRect = (*(desktopPort.visRgn))->rgnBBox;
  348.     
  349.             PenNormal();
  350.             PenMode(patXor);
  351.     
  352.             PaintRgn(_fPartMouseRegion);
  353.             Delay(30, &ticks);
  354.             PaintRgn(_fMouseRegion);
  355.     
  356.             CloseCPort(&desktopPort);
  357.             SetPort(savedPort);
  358.     
  359.     
  360.     */
  361.  
  362.     return _fMouseRegion;
  363.  
  364.     SOM_CATCH_ALL
  365.         
  366.         return kODNULL;
  367.         
  368.     SOM_ENDTRY
  369.     
  370.     return kODNULL;
  371. }
  372.  
  373. SOM_Scope void  SOMLINK ODDispatcherInvalidateFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  374. {
  375.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  376.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInvalidateFacetUnderMouse");
  377.  
  378.     SOM_TRY
  379.     
  380.         _fFacetUnderMouse = kODNULL;
  381.         somSelf->InvalidateMouseRegion(ev);
  382.         SetCursor(&ODQDGlobals.arrow);
  383.  
  384.     SOM_CATCH_ALL
  385.     SOM_ENDTRY
  386. }
  387.  
  388. SOM_Scope ODSLong  SOMLINK ODDispatcherGetSleepTime(ODDispatcher *somSelf, Environment *ev)
  389. {
  390.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  391.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetSleepTime");
  392.  
  393.     SOM_TRY
  394.     
  395.         // Don't sleep at all if another thread is ready to run:
  396.         if( ODAnyThreadsReady() )
  397.             return 0;
  398.     
  399.         const ODSLong kMaxLong = 2147483647;
  400.         const ODTicks kMaxIdleTime = kMaxLong;
  401.         
  402.     
  403.         ODTicks waitTicks = kMaxIdleTime;
  404.         
  405.         IdleListIterator iter(_fIdleList);
  406.         
  407.         for (IdleInfo* idleInfo = iter.First(); iter.IsNotComplete(); idleInfo = iter.Next())
  408.         {
  409.             waitTicks = Min(waitTicks, idleInfo->NextIdle(TickCount()));    
  410.         }
  411.         return waitTicks;
  412.  
  413.     SOM_CATCH_ALL
  414.         
  415.         return 0;
  416.     
  417.     SOM_ENDTRY
  418.     
  419.     return 0;
  420. }
  421.  
  422. static OSErr pascal HandleTSMEvents(const AppleEvent *theAppleEvent,
  423.                                         AppleEvent *reply,
  424.                                         long handlerRefcon)
  425. {
  426.     ODSession*        session = (ODSession*)handlerRefcon;
  427.     Environment*    ev = somGetGlobalEnvironment();
  428. //    DescType        eventID;
  429. //    DescType        actualType;
  430.     Size            maxSize = sizeof(DescType);
  431. //    Size            actualSize;
  432.     OSErr            result = noErr;
  433.     ODSemanticInterface* semtIntf = kODNULL; ODVolatile(semtIntf);
  434.     ODPart* keyPart = kODNULL; ODVolatile(keyPart);
  435.  
  436.     TRY
  437.         TempODFrame keyFrame
  438.             = session->GetArbitrator(ev)->AcquireFocusOwner(ev,
  439.                                                 session->Tokenize(ev,
  440.                                                                     kODKeyFocus));
  441.             // -- TÇ tempobj'd
  442.         if ((ODFrame*)keyFrame != kODNULL)
  443.         {
  444.             keyPart = keyFrame->AcquirePart(ev);
  445.             if (keyPart->HasExtension(ev, kODExtSemanticInterface))
  446.             {
  447.                 semtIntf = (ODSemanticInterface*)keyPart->AcquireExtension(ev,
  448.                                                         kODExtSemanticInterface);
  449.                 // WHAT WAS I GOING TO DO WITH THIS INFO? - NP 6/21/95
  450. //                result = AEGetAttributePtr(theAppleEvent, keyEventIDAttr,
  451. //                                                    typeType, &actualType,
  452. //                                                    (Ptr)&eventID, maxSize,
  453. //                                                    &actualSize);
  454. //                if (result || actualType != typeType || actualSize != maxSize)
  455. //                    THROW(errAEEventNotHandled);
  456.  
  457.                 // CREATE NEW ODAPPLEEVENTS FOR THE PARAMETERS
  458.                 ODAppleEvent*    odEvent = new ODAppleEvent;
  459.                 THROW_IF_NULL(odEvent);
  460.                 odEvent->InitODAppleEvent(ev);
  461.                 AEDescToODDesc((AEDesc*)theAppleEvent, odEvent);
  462.                 ODAppleEvent*    odReply = new ODAppleEvent;
  463.                 THROW_IF_NULL(odReply);
  464.                 odReply->InitODAppleEvent(ev);
  465.                 AEDescToODDesc((AEDesc*)reply, odReply);
  466.                 
  467.                 // PASS THE EVENT TO THE PART
  468.                 TRY
  469.                     semtIntf->CallEventHandler(ev, keyPart, odEvent, odReply);
  470.                 CATCH_ALL
  471.                     result = ErrorCode();
  472.                 ENDTRY
  473.                 
  474.                 // CLEAN UP. NOTE, WE MUST UPDATE THE REPLY DATAHANDLE SO THAT
  475.                 //    THE APPLE EVENTS MANAGER SEES THE CHANGE (IF ANY).
  476.                 delete odEvent;
  477.                 if (reply->descriptorType != typeNull
  478.                         && reply->dataHandle != kODNULL
  479.                         && !result)
  480.                 {
  481.                     ODByteArray data = odReply->GetRawData(ev);
  482.                     SetHandleSize(reply->dataHandle, data._length);
  483.                     THROW_IF_ERROR(MemError());
  484.                     ODBlockMove(data._buffer, *(reply->dataHandle),
  485.                                     data._length);
  486.                     DisposeByteArrayStruct(data);
  487.                 }
  488.                 delete odReply;
  489.             }
  490.             else
  491.                 result = errAEEventNotHandled;
  492.         }
  493.         else
  494.             result = errAEEventNotHandled;
  495.     CATCH_ALL
  496.         result = ErrorCode();
  497.     ENDTRY
  498.     
  499.     if ( semtIntf != kODNULL )
  500.         semtIntf->Release(ev);
  501.     if ( keyPart != kODNULL )
  502.         keyPart->Release(ev);
  503.  
  504.     return result;
  505. }
  506.  
  507. SOM_Scope void  SOMLINK ODDispatcherInitDispatcher(ODDispatcher *somSelf, Environment *ev,
  508.         ODSession* session)
  509. {
  510.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  511.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInitDispatcher");
  512.     
  513.     const Boolean    kIsSysHandler = kODTrue;
  514.  
  515.     SOM_TRY
  516.  
  517.         /* Moved from somInit. SOM itself sets fields to zero
  518.         _fExit = kODFalse;
  519.         _fDispatchTable = kODNULL;
  520.         _fSession = kODNULL;
  521.         _fIdleList = kODNULL;
  522.     
  523.         _fMouseRegion = kODNULL;
  524.         _fPartMouseRegion = kODNULL;
  525.         _fFacetUnderMouse = kODNULL;
  526.         */
  527.         
  528.         somSelf->InitObject(ev);
  529.     
  530.         _fSession = session;
  531.     
  532.         _fDispatchTable = new DispatchTable;
  533.         THROW_IF_NULL(_fDispatchTable);
  534.         
  535.         _fIdleList = new IdleList;
  536.         THROW_IF_NULL(_fIdleList);
  537.         
  538.         _fMouseRegion = ODNewRgn();
  539.             
  540.         _fPartMouseRegion = ODNewRgn();
  541.     
  542.         ODStandardDispatchModule* stdModule = kODNULL;
  543.     
  544.         stdModule =    new ODStandardDispatchModule();
  545.         THROW_IF_NULL(stdModule);
  546.         stdModule->InitStandardDispatchModule(ev,session);
  547.         
  548.         somSelf->AddDispatchModule(ev,mouseDown,  stdModule);
  549.  
  550.         somSelf->AddDispatchModule(ev,mouseUp,    stdModule);
  551.         somSelf->AddDispatchModule(ev,keyDown,    stdModule);
  552.         somSelf->AddDispatchModule(ev,keyUp,      stdModule);
  553.         somSelf->AddDispatchModule(ev,autoKey,    stdModule);
  554.         somSelf->AddDispatchModule(ev,updateEvt,  stdModule);
  555.         somSelf->AddDispatchModule(ev,diskEvt,    stdModule);
  556.         somSelf->AddDispatchModule(ev,activateEvt,stdModule);
  557.         somSelf->AddDispatchModule(ev,osEvt,      stdModule);
  558.         somSelf->AddDispatchModule(ev,kHighLevelEvent, stdModule);
  559.         somSelf->AddDispatchModule(ev,kODEvtMenu, stdModule);
  560.         somSelf->AddDispatchModule(ev,kODEvtBGMouseDown, stdModule);
  561.         somSelf->AddDispatchModule(ev,kODEvtMouseDownBorder, stdModule);
  562.         somSelf->AddDispatchModule(ev,kODEvtMouseDownEmbedded, stdModule);
  563.         somSelf->AddDispatchModule(ev,kODEvtBGMouseDownEmbedded, stdModule);
  564.         somSelf->AddDispatchModule(ev,kODEvtMouseUpEmbedded, stdModule);
  565.     
  566.         // TSM support
  567.         AEEventHandlerUPP proc = NewAEEventHandlerProc(HandleTSMEvents);
  568.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass,
  569.                                                 kUpdateActiveInputArea,
  570.                                                 proc,
  571.                                                 (long)_fSession,
  572.                                                 !kIsSysHandler));
  573.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass, kPos2Offset,
  574.                                                 proc,
  575.                                                 (long)_fSession,
  576.                                                 !kIsSysHandler));
  577.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass, kOffset2Pos,
  578.                                                 proc,
  579.                                                 (long)_fSession,
  580.                                                 !kIsSysHandler));
  581.         THROW_IF_ERROR(AEInstallEventHandler(kTextServiceClass,
  582.                                                 kShowHideInputWindow,
  583.                                                 proc,
  584.                                                 (long)_fSession,
  585.                                                 !kIsSysHandler));
  586.     
  587.         // Background mouse-down support:
  588.         ODInstallBGMouseDownHandler(session);
  589.         
  590.         // Thread support:
  591.         ODInitThreads();
  592.  
  593.     SOM_CATCH_ALL
  594.     SOM_ENDTRY
  595. }
  596.  
  597. SOM_Scope void  SOMLINK ODDispatcherInvalidateMouseRegion(ODDispatcher *somSelf, Environment *ev)
  598. {
  599.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  600.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherInvalidateMouseRegion");
  601.  
  602.     SOM_TRY
  603.  
  604.         ASSERT(_fPartMouseRegion != kODNULL, kODErrDispatcherNotInitialized);
  605.         SetEmptyRgn(_fPartMouseRegion);
  606.  
  607.     SOM_CATCH_ALL
  608.     SOM_ENDTRY
  609. }
  610.  
  611. SOM_Scope ODFacet*  SOMLINK ODDispatcherGetFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  612. {
  613.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  614.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetFacetUnderMouse");
  615.  
  616.     return _fFacetUnderMouse;
  617. }
  618.  
  619. SOM_Scope void  SOMLINK ODDispatcherSetFacetUnderMouse(ODDispatcher *somSelf, Environment *ev,
  620.         ODFacet* facet)
  621. {
  622.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  623.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherSetFacetUnderMouse");
  624.  
  625.  
  626.     _fFacetUnderMouse = facet;
  627.  
  628. }
  629.  
  630. SOM_Scope ODBoolean  SOMLINK ODDispatcherHandleNullEvent(ODDispatcher *somSelf, Environment *ev,
  631.         ODEventData* event,
  632.         ODFrame* skipFrame)
  633. {
  634.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  635.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherHandleNullEvent");
  636.  
  637.     ODBoolean handled = kODFalse;
  638.     
  639.     SOM_TRY
  640.     
  641.         // Give threads time to run:
  642.         ODYield();
  643.     
  644.         IdleListIterator iter(_fIdleList);
  645.         ODFrame* frame = kODNULL;
  646.         
  647.         for (IdleInfo* idleInfo = iter.First(); iter.IsNotComplete(); idleInfo = iter.Next())
  648.         {
  649.             if ( (idleInfo->NeedsIdle(TickCount())))
  650.             {
  651.                 frame = idleInfo->GetFrame(); 
  652.                 if ( (frame == kODNULL) || !ODObjectsAreEqual(ev, frame,skipFrame) ) 
  653.                 {
  654.                     TRY{
  655.                         idleInfo->GetPart()->HandleEvent(ev,event, frame, kODNULL, kODNULL);
  656.                     }CATCH_ALL{
  657.                         // ignore exception
  658.                     }ENDTRY
  659.                     idleInfo->SetLastIdle(TickCount());
  660.                 }
  661.             }
  662.         }
  663.         _fIdleList->RemoveUnregisteredIdlers(ev);
  664.         handled = kODTrue;
  665.  
  666.     SOM_CATCH_ALL
  667.     SOM_ENDTRY
  668.     
  669.     return handled;
  670. }
  671.  
  672. SOM_Scope ODBoolean  SOMLINK ODDispatcherMouseRegionIsInvalid(ODDispatcher *somSelf, Environment *ev)
  673. {
  674.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  675.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherMouseRegionIsInvalid");
  676.  
  677.     ODBoolean isInvalid = kODTrue;
  678.  
  679.     if (Button())
  680.         return kODFalse;
  681.     
  682.     SOM_TRY
  683.  
  684.         ASSERT(_fPartMouseRegion != kODNULL, kODErrDispatcherNotInitialized);
  685.         isInvalid = EmptyRgn(_fPartMouseRegion);
  686.  
  687.     SOM_CATCH_ALL
  688.     SOM_ENDTRY
  689.     
  690.     return isInvalid;
  691. }
  692.  
  693. SOM_Scope void  SOMLINK ODDispatcherComputeMouseRegion(ODDispatcher *somSelf, Environment *ev)
  694. {
  695.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  696.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherComputeMouseRegion");
  697.  
  698.     SOM_TRY
  699.  
  700.         somSelf->CheckFacetUnderMouse(ev); // A Part may call SetMouseRegion
  701.         /*
  702.             if no frame is under the mouse, compute an appropriate big region
  703.             either way, add the current mouse location? 
  704.             And clip region to frame shape?
  705.         */
  706.     
  707.         // Add the current mouse location to whatever region is computed by the part
  708.         Point globalMouse;
  709.         GetMouse(&globalMouse);
  710.         LocalToGlobal(&globalMouse);
  711.         
  712.         SetRectRgn(_fMouseRegion, globalMouse.h, globalMouse.v, globalMouse.h + 1, globalMouse.v + 1);
  713.         UnionRgn(_fPartMouseRegion, _fMouseRegion, _fPartMouseRegion);
  714.  
  715.     SOM_CATCH_ALL
  716.     SOM_ENDTRY
  717. }
  718.  
  719. SOM_Scope void  SOMLINK ODDispatcherCheckFacetUnderMouse(ODDispatcher *somSelf, Environment *ev)
  720. {
  721.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  722.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherCheckFacetUnderMouse");
  723.  
  724.     SOM_TRY
  725.  
  726.         Point globalPoint;
  727.         ODPoint windowPoint;
  728.     
  729.         GetMouse(&globalPoint);
  730.         LocalToGlobal(&globalPoint);
  731.     
  732.         if (!SetTSMCursor(globalPoint)) // NP: temporary. dispatcher really needs
  733.                                         //    to set a 1-pixel mouse region so that
  734.                                         //    SetTSMCursor can be called every time
  735.                                         //    the mouse moves.
  736.         {
  737.             ODWindow* odWindow = kODNULL;
  738.             ODFacet* foundFacet = kODNULL;
  739.         
  740.             ODWindowState* _fWindowState = _fSession->GetWindowState(ev); // temp
  741.             
  742.             TempODFrame mouseFocusFrame = kODNULL;
  743.             mouseFocusFrame = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev, _fSession->Tokenize(ev,kODMouseFocus));
  744.  
  745.             if (mouseFocusFrame)
  746.             {
  747.  
  748.                     if (_fFacetUnderMouse && ODObjectsAreEqual(ev, mouseFocusFrame, _fFacetUnderMouse->GetFrame(ev)))
  749.                     {
  750.                         odWindow = _fFacetUnderMouse->GetWindow(ev);
  751.                         odWindow->GetWindowPoint(ev, &globalPoint, &windowPoint);
  752.                         
  753.                         ODEventData event;
  754.                         SetEvent(event,kODEvtMouseWithin, globalPoint);
  755.                         ODEventInfo info;
  756.                         SetEventInfo(info, windowPoint);
  757.                         WindowToLocal(ev, info.where, _fFacetUnderMouse);
  758.                     
  759.                         TempODPart part = mouseFocusFrame->AcquirePart(ev);
  760. #if ODDebug && ODLogEvents
  761.     LogEvent(&event, &info, mouseFocusFrame, _fFacetUnderMouse);
  762. #endif
  763.                         part->HandleEvent(ev, &event, mouseFocusFrame, _fFacetUnderMouse, &info);
  764.                     }
  765.                     return;
  766.             }
  767.  
  768.             odWindow = _fWindowState->FindODWindow(ev, &globalPoint);
  769.                 
  770.             if (odWindow)
  771.             {
  772.                 TempODWindow tempWindow = odWindow; // ensure it's released
  773.                 odWindow->GetWindowPoint(ev, &globalPoint, &windowPoint);
  774.                 TempODFrame activeFrame = _fSession->GetArbitrator(ev)->AcquireFocusOwner(ev, _fSession->Tokenize(ev,kODSelectionFocus));
  775.                 ODFacet* activeFacet = activeFrame ? GetActiveFacetWithBorderUnderPoint(ev, activeFrame, odWindow, windowPoint) : kODNULL;
  776.                 
  777.                 if (activeFacet)
  778.                     foundFacet = activeFacet->GetContainingFacet(ev);
  779.                 else
  780.                 {
  781.                     foundFacet = odWindow->GetFacetUnderPoint(ev, &windowPoint);
  782.                     if (foundFacet && (foundFacet->GetFrame(ev)->IsFrozen(ev) || foundFacet->IsSelected(ev)))
  783.                         foundFacet = foundFacet->GetContainingFacet(ev);
  784.                 }
  785.             }
  786.         
  787.             
  788.             if (ODObjectsAreEqual(ev, foundFacet, _fFacetUnderMouse))    
  789.             {
  790.                 if (foundFacet)
  791.                 {
  792.                     ODEventData event;
  793.                     SetEvent(event,kODEvtMouseWithin, globalPoint);
  794.                     ODEventInfo info;
  795.                     SetEventInfo(info, windowPoint);
  796.                     WindowToLocal(ev, info.where, _fFacetUnderMouse);
  797.                     
  798.                     ODFrame* frame = _fFacetUnderMouse->GetFrame(ev);
  799. #if ODDebug && ODLogEvents
  800.     LogEvent(&event, &info, frame, _fFacetUnderMouse);
  801. #endif
  802.                     TempODPart part = frame->AcquirePart(ev);
  803.                     part->HandleEvent(ev, &event, frame, _fFacetUnderMouse, &info);
  804.                 }
  805.             }
  806.             else
  807.             {        
  808.                 if (_fFacetUnderMouse)
  809.                 {
  810.                     ODEventData event;
  811.                     SetEvent(event,kODEvtMouseLeave, globalPoint);
  812.                     ODEventInfo info;
  813.                     SetEventInfo(info, windowPoint);
  814.                     WindowToLocal(ev, info.where, _fFacetUnderMouse);
  815.                     
  816.                     ODFrame* frame = _fFacetUnderMouse->GetFrame(ev);
  817. #if ODDebug && ODLogEvents
  818.     LogEvent(&event, &info, frame, _fFacetUnderMouse);
  819. #endif
  820.                     TempODPart part = frame->AcquirePart(ev);
  821.                     part->HandleEvent(ev, &event, frame, _fFacetUnderMouse, &info);
  822.                 }
  823.                 if (foundFacet)
  824.                 { 
  825.                     ODEventData event;
  826.                     SetEvent(event,kODEvtMouseEnter, globalPoint);
  827.                     ODEventInfo info;
  828.                     SetEventInfo(info, windowPoint);
  829.                     WindowToLocal(ev, info.where, foundFacet);
  830.                     
  831.                     ODFrame* frame = foundFacet->GetFrame(ev);
  832. #if ODDebug && ODLogEvents
  833.     LogEvent(&event, &info, frame, foundFacet);
  834. #endif
  835.                     TempODPart part = frame->AcquirePart(ev);
  836.                     part->HandleEvent(ev, &event,frame,foundFacet, &info);
  837.                 }
  838.                 _fFacetUnderMouse = foundFacet;
  839.             }
  840.         }
  841.  
  842.     SOM_CATCH_ALL
  843.     SOM_ENDTRY
  844. }
  845.  
  846. SOM_Scope void  SOMLINK ODDispatchersomUninit(ODDispatcher *somSelf)
  847. {
  848.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  849.     ODDispatcherMethodDebug("ODDispatcher","ODDispatchersomUninit");
  850.  
  851.      ODDeleteObject(_fDispatchTable);
  852.     ODDeleteObject(_fIdleList);
  853.     ODDisposeHandle((Handle)_fMouseRegion);
  854.     ODDisposeHandle((Handle)_fPartMouseRegion);
  855.    
  856.        parent_somUninit(somSelf);
  857. }
  858.  
  859. SOM_Scope ODSize  SOMLINK ODDispatcherPurge(ODDispatcher *somSelf, Environment *ev,
  860.         ODSize size)
  861. {
  862.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  863.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherPurge");
  864.  
  865.     ODUnused(size);
  866.     return 0;
  867. }
  868.  
  869. SOM_Scope void  SOMLINK ODDispatcherAddDispatchModule(ODDispatcher *somSelf, Environment *ev,
  870.         ODEventType eventType,
  871.         ODDispatchModule* dispatchModule)
  872. {
  873.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  874.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherAddDispatchModule");
  875.  
  876.     SOM_TRY
  877.  
  878.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  879.         
  880.         if (dispatchModule)
  881.         {
  882.             _fDispatchTable->AddDispatchModule(eventType,dispatchModule);
  883.         }
  884.         else
  885.             THROW(kODErrIllegalNullDispatchModuleInput);
  886.     
  887.  
  888.     SOM_CATCH_ALL
  889.     SOM_ENDTRY
  890. }
  891.  
  892. SOM_Scope ODDispatchModule*  SOMLINK ODDispatcherGetDispatchModule(ODDispatcher *somSelf, Environment *ev,
  893.         ODEventType eventType)
  894. {
  895.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  896.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherGetDispatchModule");
  897.     
  898.     ODDispatchModule* module = kODNULL;
  899.  
  900.     SOM_TRY
  901.  
  902.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  903.     
  904.         module = _fDispatchTable->GetDispatchModule( eventType );
  905.  
  906.     SOM_CATCH_ALL
  907.     SOM_ENDTRY
  908.     
  909.     return module;
  910. }
  911.  
  912. SOM_Scope void  SOMLINK ODDispatcherRemoveDispatchModule(ODDispatcher *somSelf, Environment *ev,
  913.         ODEventType eventType)
  914. {
  915.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  916.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRemoveDispatchModule");
  917.  
  918.     SOM_TRY
  919.  
  920.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  921.         
  922.         _fDispatchTable->RemoveDispatchModule(eventType);
  923.  
  924.     SOM_CATCH_ALL
  925.     SOM_ENDTRY
  926. }
  927.  
  928. SOM_Scope void  SOMLINK ODDispatcherAddMonitor(ODDispatcher *somSelf, Environment *ev,
  929.         ODEventType eventType,
  930.         ODDispatchModule* dispatchModule)
  931. {
  932.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  933.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherAddMonitor");
  934.  
  935.     SOM_TRY
  936.  
  937.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  938.         
  939.         if (dispatchModule)
  940.             _fDispatchTable->AddMonitor(eventType,dispatchModule);        
  941.         else
  942.             THROW(kODErrIllegalNullDispatchModuleInput);
  943.  
  944.     SOM_CATCH_ALL
  945.     SOM_ENDTRY
  946. }
  947.  
  948. SOM_Scope void  SOMLINK ODDispatcherRemoveMonitor(ODDispatcher *somSelf, Environment *ev,
  949.         ODEventType eventType,
  950.         ODDispatchModule* dispatchModule)
  951. {
  952.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  953.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherRemoveMonitor");
  954.  
  955.     SOM_TRY
  956.  
  957.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  958.         
  959.         _fDispatchTable->RemoveMonitor(eventType, dispatchModule);
  960.  
  961.     SOM_CATCH_ALL
  962.     SOM_ENDTRY
  963. }
  964.  
  965.  
  966. static Boolean IntlTSMEvent(EventRecord *event) // NP: from TE 27.
  967. {
  968.     short oldFont;
  969.     ScriptCode keyboardScript;
  970.     
  971.     // make sure we have a port and it's not the Window Manager port
  972.     if (ODQDGlobals.thePort != nil && FrontWindow() != nil)
  973.     {
  974.         oldFont = ODQDGlobals.thePort->txFont;
  975.         keyboardScript = GetScriptManagerVariable(smKeyScript);
  976.         if (FontToScript(oldFont) != keyboardScript)
  977.             TextFont(GetScriptVariable(keyboardScript, smScriptAppFond));
  978.     };
  979.     return TSMEvent(event);
  980. }
  981.  
  982. SOM_Scope ODBoolean  SOMLINK ODDispatcherDispatch(ODDispatcher *somSelf, Environment *ev,
  983.         ODEventData* eventData)
  984. {
  985.     ODBoolean handled = kODFalse;
  986.     
  987.     SOM_TRY
  988.  
  989.         ODEventInfo eventInfo;    // Note: Need some utility functions
  990.         eventInfo.embeddedFrame = kODNULL;
  991.         eventInfo.embeddedFacet = kODNULL;
  992.         ODPoint zero(0,0);
  993.         eventInfo.where = zero;
  994.         eventInfo.propagated = kODFalse;
  995.     
  996.         handled =somSelf->Redispatch(ev, eventData, &eventInfo);
  997.     
  998.     SOM_CATCH_ALL
  999.     SOM_ENDTRY
  1000.     
  1001.     return handled;
  1002. }
  1003.  
  1004. SOM_Scope ODBoolean  SOMLINK ODDispatcherRedispatch(ODDispatcher *somSelf, Environment *ev,
  1005.         ODEventData* eventData,
  1006.         ODEventInfo* eventInfo)
  1007. {
  1008.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1009.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherDispatch");
  1010.  
  1011.     ODBoolean handled = kODFalse;
  1012.     ODEventType eventType = eventData->what;     
  1013.  
  1014.     SOM_TRY
  1015.  
  1016.         ASSERT(_fDispatchTable != kODNULL,kODErrDispatcherNotInitialized);
  1017.         
  1018.         {
  1019.             OrderedCollection* monitors = kODNULL;
  1020.             ODDispatchModule* module = kODNULL;
  1021.             
  1022.             monitors = _fDispatchTable->GetMonitors(eventType);
  1023.             if (monitors)
  1024.             {
  1025.                 OrderedCollectionIterator iter(monitors);
  1026.                 
  1027.                 for (module = (ODDispatchModule*) iter.First(); 
  1028.                                 iter.IsNotComplete(); 
  1029.                                 module = (ODDispatchModule*) iter.Next())
  1030.                 {
  1031.                     module->Dispatch(ev, eventData, eventInfo);
  1032.                 }
  1033.             }
  1034.             
  1035.             if (!TSMEvent((EventRecord*)eventData))
  1036.             {
  1037.                 module = _fDispatchTable->GetDispatchModule(eventType);
  1038.                 if (module)
  1039.                     handled = module->Dispatch(ev, eventData, eventInfo);
  1040.             }
  1041.         }
  1042.         // Moved to the end so that dispatch modules can monitor or patch
  1043.         // null event handling
  1044.         if ((eventType == nullEvent) && !handled)
  1045.         {
  1046.             somSelf->HandleNullEvent(ev,eventData, kODNULL);
  1047.             handled = kODTrue;
  1048.         }
  1049.             
  1050.     SOM_CATCH_ALL
  1051.     SOM_ENDTRY
  1052.     
  1053.     return handled;
  1054. }
  1055.  
  1056. SOM_Scope void  SOMLINK ODDispatcherExit(ODDispatcher *somSelf, Environment *ev)
  1057. {
  1058.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1059.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherExit");
  1060.  
  1061.     _fExit = kODTrue;
  1062. }
  1063.  
  1064. SOM_Scope ODBoolean  SOMLINK ODDispatcherShouldExit(ODDispatcher *somSelf, Environment *ev)
  1065. {
  1066.     ODDispatcherData *somThis = ODDispatcherGetData(somSelf);
  1067.     ODDispatcherMethodDebug("ODDispatcher","ODDispatcherShouldExit");
  1068.  
  1069.     return _fExit;
  1070. }
  1071.